<script setup lang="ts">
import { computed, ref, onMounted, watchEffect, useSlots } from 'vue';
import Tab from './Tab.vue';

const props = defineProps<{
  selected: string
}>();

const emit = defineEmits<{
  (e: 'update:selected', value): void
}>()

const selectedItem = ref<HTMLDivElement>();
const indicator = ref<HTMLDivElement>();
const container = ref<HTMLDivElement>();

onMounted(() => {
  watchEffect(() => {
    const { width } = selectedItem.value.getBoundingClientRect();
    indicator.value.style.width = width + 'px';
    const { left: left1 } = container.value.getBoundingClientRect();
    const { left: left2 } = selectedItem.value.getBoundingClientRect();
    const left = left2 - left1;
    indicator.value.style.left = left + 'px';
  });
});

const slots = useSlots()
const defaults = slots.default?.()
if (defaults) {
  defaults.forEach(tag => {
    if (tag.type !== Tab) {
      throw new Error('Tabs 子标签必须是 Tab');
    }
  });
}

const current = computed(() => {
  return defaults.find(tag => tag.props.title === props.selected);
});
const titles = defaults.map(tag => {
  return tag.props.title;
});
const select = (title: String) => {
  emit('update:selected', title);
};
</script>

<template>
  <div class="gulu-tabs">

    <div class="gulu-tabs-nav" ref="container">
      <div
        v-for="(itemTitle, index) in titles" :key="index"
        :ref="
          (el) => {
            if (itemTitle === selected) selectedItem = el;
          }
        "
        :class="{ selected: itemTitle === selected }" class="gulu-tabs-nav-item"
        @click="select(itemTitle)"
      >
        {{ itemTitle }}
      </div>
      <div class="gulu-tabs-nav-indicator" ref="indicator"></div>
    </div>

    <div class="gulu-tabs-content">
      <component :is="current" :key="current.props.title" class="gulu-tabs-content-item" />
    </div>

  </div>
</template>

<style lang="scss">
$blue: #40a9ff;
$color: #333;
$border-color: #d9d9d9;

.gulu-tabs {
  &-nav {
    display: flex;
    color: $color;
    border-bottom: 1px solid $border-color;
    position: relative;

    &-item {
      padding: 8px 0;
      margin: 0 16px;
      cursor: pointer;

      &:first-child {
        margin-left: 0;
      }

      &.selected {
        color: $blue;
      }
    }

    &-indicator {
      position: absolute;
      height: 3px;
      background: $blue;
      left: 0;
      bottom: -1px;
      transition: all 0.25s;
    }
  }

  &-content {
    padding: 8px 0;
  }
}
</style>
